package admin

import (
	"blog_service/model"
	"blog_service/setting"
	"crypto/sha256"
	"encoding/base64"
	"errors"
	"fmt"
	"github.com/garyburd/redigo/redis"
	"github.com/gin-gonic/gin"
	"net/http"
	"strconv"
	"time"
)

type DataJson map[string]string

func SHA256(str string) string {
	hash := sha256.New()
	_, err := hash.Write([]byte(str))
	if err != nil {
		return ""
	}

	result := base64.StdEncoding.EncodeToString(hash.Sum([]byte("")))
	return result
}

func CreateRedisConn() (redis.Conn, error) {
	conn, err := redis.Dial("tcp", setting.Redis)
	if err == nil {
		conn.Do("auth", setting.RedisPwd)
	}
	return conn, err
}

func ReadArticle(ctx *gin.Context) (*model.Article, error) {

	typeId, err := strconv.Atoi(ctx.PostForm("typeId"))
	if err != nil {
		ctx.JSON(400, gin.H{"err": "request err"})
		return nil, err
	}

	showDate, err := strconv.Atoi(ctx.PostForm("showDate"))
	if err != nil {
		ctx.JSON(400, gin.H{"err": "request err"})
		return nil, err
	}

	articleTitle := ctx.PostForm("articleTitle")
	articleContent := ctx.PostForm("articleContent")
	introductory := ctx.PostForm("introducemd")

	if articleTitle == "" || articleContent == "" || introductory == "" {
		ctx.JSON(400, gin.H{"err": "request err must not null"})
		return nil, errors.New("data have null value")
	}

	article := model.Article{
		TypeId:         uint(typeId),
		AddTime:        showDate,
		Title:          articleTitle,
		ArticleContent: articleContent,
		Introduce:      introductory,
		ViewCount:      0,
	}

	return &article, nil
}

func Login(ctx *gin.Context) {
	username := ctx.PostForm("username")
	password := ctx.PostForm("password")
	if username == "" || password == "" {
		ctx.JSON(401, DataJson{"Data": "must not null"})
		return
	}

	user := new(model.AdminUser)

	password = SHA256(password)

	model.Db.Where("username = ? AND password = ?", username, password).First(user)

	if user.Username == "" {
		ctx.JSON(401, DataJson{"Data": "password or username is error"})
		return
	}

	pwd := user.Username + strconv.Itoa(int(time.Now().Unix()))
	pwd = SHA256(pwd)

	//Redis 链接
	conn, err := CreateRedisConn()
	if err != nil {
		ctx.JSON(500, DataJson{"Data": "登入失败"})
		return
	}

	defer conn.Close()

	_, err = conn.Do("SETEX", username, 24*6*3600, pwd)
	if err != nil {
		fmt.Println(err)
		ctx.JSON(500, DataJson{"Data": "登入失败"})
		return
	}

	ctx.JSON(http.StatusOK, DataJson{"Data": "登入成功", "openId": pwd})

}

func AddArticle(ctx *gin.Context) {

	article, err := ReadArticle(ctx)
	if err != nil {
		return
	}

	model.Db.Create(article)

	articleLast := model.Article{}
	model.Db.Last(&articleLast)

	if articleLast.AddTime == article.AddTime {
		ctx.JSON(200, gin.H{"articleId": articleLast.ID})
		return
	} else {
		ctx.JSON(400, gin.H{"err": "keeping"})
		return
	}

}

func UpdateArticle(ctx *gin.Context) {
	article, err := ReadArticle(ctx)
	if err != nil {
		return
	}

	articleId, err := strconv.Atoi(ctx.PostForm("articleId"))

	if err != nil {
		ctx.JSON(400, "not articleId")
		return
	}

	article.ID = uint(articleId)
	model.Db.Save(article)
	ctx.JSON(200, "OK")
	return

}

func DeleteArticle(ctx *gin.Context) {
	articleId, err := strconv.Atoi(ctx.PostForm("articleId"))

	if err != nil {
		ctx.JSON(400, "not articleId")
		return
	}

	article := new(model.Article)
	article.ID = uint(articleId)
	model.Db.Delete(article)

}
